﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Dynamic;
using System.Data.Entity;
using BugTracker.DataAccess.Data;

namespace BugTracker.BusinessLogic.Issue.Details
{
    public class IssueDetailService : IIssueDetailService
    {
        private BugTrackerEntities db = null;

        public IssueDetailService(BugTrackerEntities db)
        {
            if (db == null)
                throw new ArgumentNullException("db");
            this.db = db;
        }

        public IList<BusinessEntities.Entities.Issue.IssueDetail> PageSortWhere(
            int pageIndex, int pageSize, 
            string whereClause, 
            string sortExpression, 
            out int count)
        {
            count = (from models in db.Issues
                           where models.IsDeleted == false
                           select models)
                           .Where(whereClause).Count();

            var results = (from models in db.Issues
                           join categories in db.Categories on models.CategoryID equals categories.CategoryID
                           join types in db.IssueTypes on models.IssueTypeID equals types.IssueTypeID
                           join priorities in db.IssuePriorityTypes on models.IssuePriorityTypeID equals priorities.IssuePriorityTypeID
                           join status in db.IssueStatusTypes on models.IssueStatusTypeID equals status.IssueStatusTypeID
                           join assignee in db.BTUsers on models.IssueAssigneeID equals assignee.BTUserID
                           join projects in db.Projects on models.ProjectID equals projects.ProjectID
                           join severities in db.IssueSeverityTypes on models.IssueSeverityTypeID equals severities.IssueSeverityTypeID
                           join resolutions in db.IssueResolutionTypes on models.IssueResolutionTypeID equals resolutions.IssueResolutionTypeID
                           join reproduced in db.Reproduceds on models.ReproducedID equals reproduced.ReproducedID
                           join reportedby in db.ReportedBies on models.ReportedByID equals reportedby.ReportedByID
                           where models.IsDeleted == false
                           select new BusinessEntities.Entities.Issue.IssueDetail
                               { 
                                    IssueID = models.IssueID,
                                    CategoryID = models.CategoryID,
                                    Name = models.Name,
                                    Description = models.Description,
                                    IssueTypeID = models.IssueTypeID,
                                    IssuePriorityTypeID = models.IssuePriorityTypeID,
                                    IssueStatusTypeID = models.IssueStatusTypeID,
                                    IssueAssigneeID = models.IssueAssigneeID,
                                    ProjectID = models.ProjectID,
                                    Comments = models.Comments,
                                    IssueSeverityTypeID = models.IssueSeverityTypeID,
                                    IssueResolutionTypeID = models.IssueResolutionTypeID,
                                    ReproducedID = models.ReproducedID,
                                    ReportedOn = models.ReportedOn,
                                    ReportedByID = models.ReportedByID,
                                    ResolvedOn = models.ResolvedOn,
                                    IsActive = models.IsActive,
                                    IsDeleted = models.IsDeleted,
                                    RowGuid = models.RowGuid,
                                    CreatedOn = models.CreatedOn,
                                    ModifiedOn = models.ModifiedOn,
                                    UserId = models.UserId ?? Guid.Empty,
                                    CategoryType = categories.Name,
                                    IssueType = types.Name,
                                    IssuePriorityType = priorities.Name,
                                    IssueStatusType = status.Name,
                                    IssueAssignee = (assignee.FirstName + " " + assignee.LastName),
                                    ProjectName = projects.Name,
                                    IssueSeverityType = severities.Name,
                                    IssueResolutionType = resolutions.Name,
                                    IssueReproductionType = reproduced.Name,
                                    ReportedBy = (reportedby.FirstName + " " + reportedby.LastName)
                               }
                           )
                           .Where(whereClause)
                           .OrderBy(sortExpression)
                           .Skip(pageIndex * pageSize)
                           .Take(pageSize);
            return results.ToList<BusinessEntities.Entities.Issue.IssueDetail>();
        }

        public IList<BusinessEntities.Entities.Issue.IssueDetail> Report()
        {
            var results = (from models in db.Issues
                           join categories in db.Categories on models.CategoryID equals categories.CategoryID
                           join types in db.IssueTypes on models.IssueTypeID equals types.IssueTypeID
                           join priorities in db.IssuePriorityTypes on models.IssuePriorityTypeID equals priorities.IssuePriorityTypeID
                           join status in db.IssueStatusTypes on models.IssueStatusTypeID equals status.IssueStatusTypeID
                           join assignee in db.BTUsers on models.IssueAssigneeID equals assignee.BTUserID
                           join projects in db.Projects on models.ProjectID equals projects.ProjectID
                           join severities in db.IssueSeverityTypes on models.IssueSeverityTypeID equals severities.IssueSeverityTypeID
                           join resolutions in db.IssueResolutionTypes on models.IssueResolutionTypeID equals resolutions.IssueResolutionTypeID
                           join reproduced in db.Reproduceds on models.ReproducedID equals reproduced.ReproducedID
                           join reportedby in db.ReportedBies on models.ReportedByID equals reportedby.ReportedByID
                           where models.IsDeleted == false
                           select new BusinessEntities.Entities.Issue.IssueDetail
                           {
                               IssueID = models.IssueID,
                               CategoryID = models.CategoryID,
                               Name = models.Name,
                               Description = models.Description,
                               IssueTypeID = models.IssueTypeID,
                               IssuePriorityTypeID = models.IssuePriorityTypeID,
                               IssueStatusTypeID = models.IssueStatusTypeID,
                               IssueAssigneeID = models.IssueAssigneeID,
                               ProjectID = models.ProjectID,
                               Comments = models.Comments,
                               IssueSeverityTypeID = models.IssueSeverityTypeID,
                               IssueResolutionTypeID = models.IssueResolutionTypeID,
                               ReproducedID = models.ReproducedID,
                               ReportedOn = models.ReportedOn,
                               ReportedByID = models.ReportedByID,
                               ResolvedOn = models.ResolvedOn,
                               IsActive = models.IsActive,
                               IsDeleted = models.IsDeleted,
                               RowGuid = models.RowGuid,
                               CreatedOn = models.CreatedOn,
                               ModifiedOn = models.ModifiedOn,
                               UserId = models.UserId ?? Guid.Empty,
                               CategoryType = categories.Name,
                               IssueType = types.Name,
                               IssuePriorityType = priorities.Name,
                               IssueStatusType = status.Name,
                               IssueAssignee = (assignee.FirstName + " " + assignee.LastName),
                               ProjectName = projects.Name,
                               IssueSeverityType = severities.Name,
                               IssueResolutionType = resolutions.Name,
                               IssueReproductionType = reproduced.Name,
                               ReportedBy = (reportedby.FirstName + " " + reportedby.LastName)
                           }
                           );
            return results.ToList<BusinessEntities.Entities.Issue.IssueDetail>();
        }
    }
}
